﻿using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json;
using NoIdeaIoc;
using System.Text.Encodings.Web;
using System.Text.Unicode;
using NoIdeaIoc.Logger;

namespace NoIdeaSelfHost.Codes;

/// <summary>
/// 系统服务
/// </summary>
public class Service : IHostService
{
    /// <summary>
    /// 系统服务
    /// </summary>
    public Service() { }
    static IHostBuilder CreateWebHostBuilder(int port, string[] args)
    {
        return Host.CreateDefaultBuilder(args)
          .UseServiceProviderFactory(new LifeTimeFactory(OnBuildingContainer))
          .ConfigureWebHostDefaults(webBuilder =>
          {
              webBuilder.UseStartup<Startup>()
              .UseKestrel(x =>
              {
                  x.Listen(System.Net.IPAddress.Any, port, y =>
                  {
                      y.Protocols = HttpProtocols.Http1AndHttp2;
                      //使用ssl证书
                      //y.UseHttps("", "");
                  });
              });
          });
    }
    // 配置注入容器方法
    static void OnBuildingContainer(IContainerBuilder builder)
    {
        builder
        .Configure<KestrelServerOptions>(options =>
        {
            options.Limits.MaxRequestBodySize = defaultMaxRequestBodySize; // 设置最大请求体大小
                                                                           //options.AllowSynchronousIO = true;
        }).Configure<IISServerOptions>(options =>
        {
            options.MaxRequestBodySize = defaultMaxRequestBodySize; // 设置最大请求体大小
                                                                    //options.AllowSynchronousIO = true;
        });
        builder.Configure<FormOptions>(formOptions =>
        {
            formOptions.ValueLengthLimit = int.MaxValue; // 表单内容大小限制，默认4194304，单位byte
            formOptions.MultipartBodyLengthLimit = int.MaxValue; // 如果是multipart，默认134217728
        })
        .AddCors(options =>
        {
            // CorsPolicy 是自訂的 Policy 名稱
            options.AddPolicy("CorsPolicy", policy =>
            {
                policy.SetPreflightMaxAge(TimeSpan.FromSeconds(1800L));//update by jason
                policy.AllowAnyOrigin()
                      .AllowAnyHeader()
                      .AllowAnyMethod();
            });
        })
        .AddHttpClient()
        .AddSingleton<IHttpContextAccessor, HttpContextAccessor>()
        // Asp.Net Core 3.1 WebApi项目 可以在StartUp.cs的ConfigureServices方法中添加
        //.AddScoped<IServiceScope, DefaultServiceScope>()
        .AddSingleton<IServiceScopeFactory, DefaultServiceScopeFactory>()
        .AddSingleton<ILogFactory, DefaultLoggerFactory>()
        .AddSingleton<ILogger, ConsoleLog>()
        //.AddSingleton<ILoggerFactory, DefaultLoggerFactory>()
        .AddAuthorization()
        //.AddControllers()
        .AddControllers(config =>
        {
            config.ReturnHttpNotAcceptable = true;
        })
        .AddJsonOptions(options =>
        {
            options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);
            options.JsonSerializerOptions.PropertyNamingPolicy = null;
        })
        .AddNewtonsoftJson(options =>
        {
            // Use the default property (Pascal) casing
            options.SerializerSettings.ContractResolver = new DefaultContractResolver();
            options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
            options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
            options.SerializerSettings.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
            options.SerializerSettings.DateParseHandling = DateParseHandling.DateTime;
            options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
        })
        ;
    }
    /// <summary>
    /// 默认允许最大请求体大小(500MB)
    /// </summary>
    const int defaultMaxRequestBodySize = 500 * 1024 * 1024;
    IHost host;
    /// <summary>
    /// 服务启动时
    /// </summary>
    /// <returns></returns>
    public async Task<bool> StartAsync()
    {
        host = CreateWebHostBuilder(50000, null).Build();
        ThreadPool.QueueUserWorkItem(async x =>
        {
            try
            {
                await (x as IHost).RunAsync().ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }, host);
        return true;
    }
    /// <summary>
    /// 服务关闭时
    /// </summary>
    /// <returns></returns>
    public async Task<bool> StopAsync()
    {
        await host.StopAsync().ConfigureAwait(false);
        host.Dispose();
        return true;
    }
}